package com.freelancer.musicinstruction.services.impl.youtube;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

import com.freelancer.musicinstruction.beans.interfaces.MusicInstruction;
import com.freelancer.musicinstruction.beans.youtube.YoutubeVideo;


/** Youtube Search Handler for RSS Feeds
 *  Other feed formats should have separate SAX Handlers
 * @author Akalugwu Charles
 *
 */
public class YoutubeFeedHandler extends DefaultHandler {
	
	private static final String TAG = YoutubeFeedHandler.class.getSimpleName();
	
	private boolean inItem = false;
	private boolean thumbnailExtracted = false;
	private boolean inTotalResults = false;
	private boolean inPubDate = false;
	private boolean inTitle = false;
	private boolean inLink = false;
	private boolean inDescription = false;
	private boolean inUploaded = false;
	private boolean inVideoid = false;
	private boolean inCredit = false;
	
	
	private List<MusicInstruction> videoCache;
	
	private YoutubeVideo youtubeVideo;
	
	private Integer videosAdded;
	
	private String searchResultsCount;
	
	private Integer videoNumberLimit;
	
	private StringBuilder textBuilder;
	
	public YoutubeFeedHandler( Integer limit ){
		
		videosAdded = new Integer(0);
		youtubeVideo = new YoutubeVideo();
		videoCache = new ArrayList<MusicInstruction>();
		textBuilder = new StringBuilder();
		videoNumberLimit = limit;
		//Log.d(TAG, "contructor called");
	}
	
	public List<MusicInstruction> getVideos(){
		return videoCache;
	}
	
	
	public String getSearchResultsCount(){
		if( searchResultsCount != null ){
			return searchResultsCount;
		}
		else{
			return "0";
		}
	}
	
	
	private void resetHandler( ){
		videosAdded = new Integer( 0 );
		youtubeVideo = new YoutubeVideo();
		videoCache = new ArrayList<MusicInstruction>();
		
	}
	
	
	private void resetVideo(){
		youtubeVideo = new YoutubeVideo();
	}
	
	private void resetVideoCache(){
		videoCache = new ArrayList<MusicInstruction>();
	}
	
	
	private void resetTextBuilder(){
		textBuilder = new StringBuilder();
	}
	
	
	
	public void startElement(String uri, String name, String qName,Attributes atts) {
		
		
		//Log.d ( TAG, "name = "+ name);
		//Log.d ( TAG, "qName = "+ qName);
		
		String element = name.trim();
		//Log.d ( TAG, "startElement found: "+ name );
		
		if( element.equals( "totalResults")){
			inTotalResults = true;
		}
		else if( element.equals( "item" )){
			resetVideo();
			inItem = true;
		}
		else if ( element.equals( "pubDate" )){
			inPubDate = true;
		}
		else if ( element.equals( "title" ) && inItem){
			inTitle = true;
		}
		else if ( element.equals( "link" ) && inItem){
			inLink = true;
			resetTextBuilder();
		}
		else if ( element.equals( "feedLink")){
			youtubeVideo.setCommentFeedUrl( atts.getValue( 0 ));
			youtubeVideo.setCommentCounter( atts.getValue( 1 ));
		}
		else if ( element.equals( "description")){
			inDescription = true;
		}
		else if ( element.equals( "thumbnail") && !thumbnailExtracted){
			youtubeVideo.setThumbnailURL( atts.getValue( 0 ));
			youtubeVideo.setThumbnailHeight( atts.getValue( 1 ));
			youtubeVideo.setThumbnailWidth( atts.getValue( 2 ));
		}
		else if ( element.equals( "duration")){
			youtubeVideo.setVideoLength( atts.getValue( 0 ));
		}
		else if ( element.equals( "uploaded")){
			inUploaded = true;
		}
		else if ( element.equals( "videoid")){
			inVideoid = true;
		}
		else if ( element.equals( "rating")){
			youtubeVideo.setVideoRating( atts.getValue( 0 ));
		}
		else if ( element.equals( "statistics")){
			youtubeVideo.setVideoFavoriteCount( atts.getValue( 0 ));
			youtubeVideo.setVideoViewCount( atts.getValue( 1 ));
		}
		else if ( element.equals( "credit")){
			inCredit = true;
		}
		
	}
	
	
	
	public void characters(char chars[], int start, int length) {
		
		//String text = (new String(chars).substring(start, start + length));
		String text = new String(chars, start, length);
		
		
		if ( inTotalResults ){
			searchResultsCount = text;
			resetHandler();
			//vc.setSearchResultCount( Long.parseLong( text ) );
			//Log.d(TAG, "***Search Result = "+text);
		}
		else if ( inPubDate ){
			youtubeVideo.setPublishDate( text );
		}
		else if ( inTitle ){
			youtubeVideo.setVideoTitle( text );
		}
		else if ( inLink ){
			textBuilder.append( text);
		}
		else if ( inCredit ){
			//Log.d(TAG, "uploader = "+text );
			youtubeVideo.setVideoUploader( text );
		}
		else if ( inDescription ){
			youtubeVideo.setVideoDescription( text );
		}
		else if ( inUploaded ){
			youtubeVideo.setVideoUploadDate( text );
		}
		else if ( inVideoid ){
			youtubeVideo.setVideoID( text );
		}
		
	}
	
	
	
	public void endElement(String uri, String name, String qName) throws SAXException{
		
		String element = name.trim();
		//Log.d ( TAG, "endElement found: "+ name + " [videos added = "+videosAdded+" videos_max_count = "+videoNumberLimit);
		
		
		if( element.equals( "totalResults")){
			inTotalResults = false;
		}
		else if( element.equals( "item" )){
			//Log.d ( TAG, "entered into item element" );
			inItem = false;
			thumbnailExtracted = false;
			
			//Log.d(TAG, "about to add video (name = "+ yv.getVideoTitle()+ " )");

			if( videosAdded >= videoNumberLimit ){
		
					Log.d ( TAG, "Video Limit Reached = : "+ videoNumberLimit );
					throw new SAXException( "query limit satisfied - displaying videos (total = "+ videoNumberLimit );
			}
			else{
				videoCache.add( youtubeVideo );
				videosAdded++;
				//Log.d ( TAG, "Number of Videos = : "+ videosAdded );
				//Log.d(TAG, "added video: "+yv.getVideoTitle() + " video count: "+videosAdded );
			}

			
		}
		else if ( element.equals( "pubDate" )){
			inPubDate = false;
		}
		else if ( element.equals( "title" ) && inItem){
			inTitle = false;
		}
		else if ( element.equals( "link" ) && inItem){
			inLink = false;
			youtubeVideo.setVideoLink( textBuilder.toString() );
			//Log.d(TAG, "video link: "+sb.toString());
			resetTextBuilder();
		}
		else if ( element.equals( "feedLink")){
			;
		}
		else if ( element.equals( "description")){
			inDescription = false;
		}
		else if ( element.equals( "thumbnail") && !thumbnailExtracted){
			thumbnailExtracted = true;
			
		}
		else if ( element.equals( "duration" )){
					;
		}
		else if ( element.equals( "uploaded" )){
			inUploaded = false;
		}
		else if ( element.equals( "videoid" )){
			inVideoid = false;
		}
		else if ( element.equals( "rating" )){
			;
		}
		else if ( element.equals( "statistics" )){
			;	
		}
		else if ( element.equals( "credit")){
			inCredit=false;
		}
		
	}
	
	public void startDocument( ) throws SAXException {
		//Log.d(TAG, "startDocument found");
	}
	
	public void endDocument( ) throws SAXException {
		//Log.d ( TAG, "endDocument found = : "+ videosAdded );
		throw new SAXException( "found only " + videosAdded + " queries matching your request" );
	}
	
}
